﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Physis.Enterprise {

    public class EnterpriseFactory : FactoryBase {
        
        #region Private Properties

        #endregion 


        #region Public Properties


        #endregion 


        #region Constructors

        public EnterpriseFactory (Application forApplication) : base (forApplication) { return; }

        #endregion 


        #region Factories
        
        public List<Enterprise.Environment> Environments (Boolean useCaching = false) {

            List<Enterprise.Environment> environments = new List<Enterprise.Environment> ();

            ClearLastException ();

            try {

                String selectStatement = "SELECT * FROM Environment ORDER BY Name";

                System.Data.DataTable dataTable = Application.EnterpriseDatabase.SelectDataTable (selectStatement);

                foreach (System.Data.DataRow currentDataRow in dataTable.Rows) {

                    Enterprise.Environment environment = new Enterprise.Environment (Application);

                    environment.MapDataFields (currentDataRow);

                    environments.Add (environment);

                }

            }

            catch (Exception applicationException) {

                SetLastException (applicationException);

            }

            return environments;

        }

        public List<Enterprise.Environment> EnvironmentsByUserAccountId (Int64 userAccountId, Boolean useCaching = false) {

            List<Enterprise.Environment> environments = new List<Enterprise.Environment> ();

            ClearLastException ();

            try {

                String selectStatement = "SELECT DISTINCT Environment.* FROM Environment \r\n";

                selectStatement += "    JOIN Role ON Environment.Id = Role.EnvironmentId \r\n";

                selectStatement += "    JOIN RoleMembership ON Role.Id = RoleMembership.RoleId \r\n";

                selectStatement += "  WHERE RoleMembership.UserAccountId = " + userAccountId + "\r\n";

                selectStatement += "  ORDER BY Environment.Name";

                System.Data.DataTable dataTable = Application.EnterpriseDatabase.SelectDataTable (selectStatement);

                foreach (System.Data.DataRow currentDataRow in dataTable.Rows) {

                    Enterprise.Environment environment = new Enterprise.Environment (Application);

                    environment.MapDataFields (currentDataRow);

                    environments.Add (environment);

                }

            }

            catch (Exception applicationException) {

                SetLastException (applicationException);

            }

            return environments;

        }


        public Enterprise.Environment Environment (Int64 id, Boolean useCaching = false) {

            if (id == 0) { return null; }

            String cacheKey = "Physis.Application.Environment." + id; 

            Enterprise.Environment environment = null;

            ClearLastException ();

            try {

                if (useCaching) { environment = (Enterprise.Environment)CacheManager.GetObject (cacheKey); }

                if (environment == null) {

                    environment = new Enterprise.Environment (Application, id);

                    CacheManager.CacheObject (cacheKey, environment, CacheExpirationData);

                }

            }

            catch (Exception applicationException) {

                SetLastException (applicationException);

            }

            return environment;

        }

        public Enterprise.Environment Environment (String name, Boolean useCaching = false) {

            if (String.IsNullOrWhiteSpace (name)) { return null; }

            String cacheKey = "Physis.Application.Environment." + name;

            Enterprise.Environment environment = null;

            ClearLastException ();

            try {

                if (useCaching) { environment = (Enterprise.Environment)CacheManager.GetObject (cacheKey); }

                if (environment == null) {

                    environment = new Enterprise.Environment (Application, name);

                    CacheManager.CacheObject (cacheKey, environment, CacheExpirationData);

                }

            }

            catch (Exception applicationException) {

                SetLastException (applicationException);

            }

            return environment;

        }

        #endregion 

    }

}
